/**
 * @p.md
 * 
 * SQLiteProvider 是一个基于 SQLite 数据库的持久化提供者
 * 
 * 注意：使用此提供者需要安装 better-sqlite3 依赖:
 * ```
 * npm install better-sqlite3
 * ```
 */
import Database from 'better-sqlite3';
import { PersistenceProvider } from './persistenceProvider';

// SQLite 类型定义
interface SQLiteRow {
  [key: string]: any;
}

/**
 * SQLite 持久化提供者，用于将事件和快照持久化到 SQLite 数据库
 */
export class SQLiteProvider implements PersistenceProvider {
  private db: Database;
  private initialized: boolean = false;
  
  /**
   * 构造函数
   * @param dbPath 数据库文件路径，默认为 './persistence/protoactor.db'
   */
  constructor(dbPath: string = './persistence/protoactor.db') {
    this.db = new Database(dbPath);
    this.initialize();
  }
  
  /**
   * 初始化数据库表
   */
  private async initialize(): Promise<void> {
    if (this.initialized) return;
    
    try {
      // 创建事件表
      this.db.exec(`
        CREATE TABLE IF NOT EXISTS events (
          persistence_id TEXT NOT NULL,
          event_index INTEGER NOT NULL,
          event_data TEXT NOT NULL,
          timestamp INTEGER NOT NULL,
          PRIMARY KEY (persistence_id, event_index)
        )
      `);
      
      // 创建快照表
      this.db.exec(`
        CREATE TABLE IF NOT EXISTS snapshots (
          persistence_id TEXT NOT NULL,
          snapshot_index INTEGER NOT NULL,
          snapshot_data TEXT NOT NULL,
          timestamp INTEGER NOT NULL,
          PRIMARY KEY (persistence_id, snapshot_index)
        )
      `);
      
      this.initialized = true;
    } catch (err) {
      console.error('初始化 SQLiteProvider 失败:', err);
      throw err;
    }
  }
  
  /**
   * 关闭数据库连接
   */
  public close(): Promise<void> {
    return Promise.resolve(this.db.close());
  }
  
  /**
   * 获取指定持久化 ID 的事件
   * @param persistenceId 持久化 ID
   * @param fromIndex 开始索引（包含）
   * @param toIndex 结束索引（包含）
   * @returns 事件数组
   */
  async getEventsByPersistenceId(persistenceId: string, fromIndex: number, toIndex: number): Promise<any[]> {
    await this.initialize();
    
    try {
      const stmt = this.db.prepare(`
        SELECT event_data FROM events 
        WHERE persistence_id = ? AND event_index >= ? AND event_index <= ?
        ORDER BY event_index ASC
      `);
      
      const rows = stmt.all(persistenceId, fromIndex, toIndex) as SQLiteRow[];
      return rows.map(row => JSON.parse(row.event_data));
    } catch (err) {
      console.error('获取事件失败:', err);
      throw err;
    }
  }
  
  /**
   * 获取指定持久化 ID 的最新快照
   * @param persistenceId 持久化 ID
   * @returns 快照数据，如果不存在则返回 null
   */
  async getSnapshotByPersistenceId(persistenceId: string): Promise<any | null> {
    await this.initialize();
    
    try {
      const stmt = this.db.prepare(`
        SELECT snapshot_data FROM snapshots 
        WHERE persistence_id = ? 
        ORDER BY snapshot_index DESC 
        LIMIT 1
      `);
      
      const row = stmt.get(persistenceId) as SQLiteRow | undefined;
      
      if (!row) return null;
      return JSON.parse(row.snapshot_data);
    } catch (err) {
      console.error('获取快照失败:', err);
      throw err;
    }
  }
  
  /**
   * 持久化事件
   * @param persistenceId 持久化 ID
   * @param eventIndex 事件索引
   * @param event 事件数据
   */
  async persistEvent(persistenceId: string, eventIndex: number, event: any): Promise<void> {
    await this.initialize();
    
    try {
      const timestamp = Date.now();
      const eventData = JSON.stringify(event);
      
      const stmt = this.db.prepare(`
        INSERT OR REPLACE INTO events (persistence_id, event_index, event_data, timestamp) 
        VALUES (?, ?, ?, ?)
      `);
      
      stmt.run(persistenceId, eventIndex, eventData, timestamp);
    } catch (err) {
      console.error('持久化事件失败:', err);
      throw err;
    }
  }
  
  /**
   * 持久化快照
   * @param persistenceId 持久化 ID
   * @param snapshotIndex 快照索引
   * @param snapshot 快照数据
   */
  async persistSnapshot(persistenceId: string, snapshotIndex: number, snapshot: any): Promise<void> {
    await this.initialize();
    
    try {
      const timestamp = Date.now();
      const snapshotData = JSON.stringify(snapshot);
      
      const stmt = this.db.prepare(`
        INSERT OR REPLACE INTO snapshots (persistence_id, snapshot_index, snapshot_data, timestamp) 
        VALUES (?, ?, ?, ?)
      `);
      
      stmt.run(persistenceId, snapshotIndex, snapshotData, timestamp);
    } catch (err) {
      console.error('持久化快照失败:', err);
      throw err;
    }
  }
  
  /**
   * 删除事件
   * @param persistenceId 持久化 ID
   * @param fromIndex 开始索引（包含）
   * @param toIndex 结束索引（包含）
   */
  async deleteEvents(persistenceId: string, fromIndex: number, toIndex: number): Promise<void> {
    await this.initialize();
    
    try {
      const stmt = this.db.prepare(`
        DELETE FROM events 
        WHERE persistence_id = ? AND event_index >= ? AND event_index <= ?
      `);
      
      stmt.run(persistenceId, fromIndex, toIndex);
    } catch (err) {
      console.error('删除事件失败:', err);
      throw err;
    }
  }
  
  /**
   * 删除快照
   * @param persistenceId 持久化 ID
   * @param fromIndex 开始索引（包含）
   * @param toIndex 结束索引（包含）
   */
  async deleteSnapshots(persistenceId: string, fromIndex: number, toIndex: number): Promise<void> {
    await this.initialize();
    
    try {
      const stmt = this.db.prepare(`
        DELETE FROM snapshots 
        WHERE persistence_id = ? AND snapshot_index >= ? AND snapshot_index <= ?
      `);
      
      stmt.run(persistenceId, fromIndex, toIndex);
    } catch (err) {
      console.error('删除快照失败:', err);
      throw err;
    }
  }
} 